package personal.lijun.skeleton.web.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Description;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.vote.UnanimousBased;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.expression.WebExpressionVoter;
import org.springframework.session.web.http.DefaultCookieSerializer;
import personal.lijun.skeleton.web.access.CalendarPermissionEvaluator;
import personal.lijun.skeleton.web.access.expression.CustomWebSecurityExpressionHandler;
import personal.lijun.skeleton.web.authentication.CalendarUserAuthenticationProvider;
import personal.lijun.skeleton.web.feign.CalendarServiceFeign;

import java.util.Arrays;
import java.util.List;

/**
 * @Auther: lijun@sstcsoft.com
 * @Date: 2019/9/16 18:01
 */
@Configuration
public class CustomAuthorizationConfig {

    @Description("DefaultMethodSecurityExpressionHandler")
    @Bean
    public DefaultMethodSecurityExpressionHandler defaultExpressionHandler(CalendarServiceFeign eventDao){
        DefaultMethodSecurityExpressionHandler deh = new DefaultMethodSecurityExpressionHandler();
        deh.setPermissionEvaluator(
                new CalendarPermissionEvaluator(eventDao));
        return deh;
    }

    @Description("AccessDecisionManager for Authorization voting")
    @Bean
    public AccessDecisionManager accessDecisionManager(
            CustomWebSecurityExpressionHandler customWebSecurityExpressionHandler) {
        List<AccessDecisionVoter<? extends Object>> decisionVoters
                = Arrays.asList(
//                        new WebExpressionVoter()
                new WebExpressionVoter(){{
                    setExpressionHandler(customWebSecurityExpressionHandler);
                }}
        );
        return new UnanimousBased(decisionVoters);
//        return new ConsensusBased(decisionVoters);
    }

    @Description("AuthenticationMnager that will generate an authentication token unlike {PreAuthenticatedAuthenticationProvider}")
    @Bean
//    @DependsOn({"calendarServiceFeign"})
    public CalendarUserAuthenticationProvider calendarUserAuthenticationProvider(
            CalendarServiceFeign calendarService,
            PasswordEncoder passwordEncoder){
        return new CalendarUserAuthenticationProvider(calendarService, passwordEncoder);
    }

//    @Bean
//    public CookieHttpSessionStrategy cookieHttpSessionStrategy() {
//        CookieHttpSessionStrategy strategy = new CookieHttpSessionStrategy();
//        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
//        cookieSerializer.setCookieName("gs");
//        cookieSerializer.setCookiePath("/");
//        cookieSerializer.setCookieMaxAge(60 * 60 * 24 * 30);
//        strategy.setCookieSerializer(cookieSerializer);
//        return strategy;
//    }
}
